<?php
namespace CustomerForm;

use Illuminate\Support\Facades\DB;

/**
 * 自定义表单引擎
 * Class CustomerFormEngine
 * @package CustomerForm
 */
class CustomerFormEngine {

    //状态:正常
    public static $STATUS_OK = 1;

    //状态:禁止修改
    public static $STATUS_NOT_UPDATE = 2;

    //状态:禁止查看
    public static $STATUS_NOT_GET = 3;

    //状态:删除
    public static $STATUS_DELETE = 9;

    //类型：其他
    public static $TYPE_OTHER = 0;

    /**
     * 检测当前结构是否是自定义表单创建结构
     * @param $formStruct 自定义表单结构
     * @param bool $isEdit 是否检测编辑结构
     * @return array
     */
    public static function checkIsCustomerFormStruct($formStruct, $isEdit = false) {
        if (is_string($formStruct)) {
            $formStruct = json_decode($formStruct, true);
        }

        if (!is_array($formStruct) || !$formStruct) {
            return self::ModelReturn(1, '自定义表单结构不正确');
        }

        $allSort = [];
        foreach ($formStruct as &$item) {
            if ($isEdit) {
                $isFalse = array_key_exists('type', $item) && array_key_exists('label', $item) &&  array_key_exists('ext', $item) && array_key_exists('value', $item) && array_key_exists('sort', $item) &&  array_key_exists('id', $item) ? true : false;
            } else {
                $isFalse = array_key_exists('type', $item) && array_key_exists('label', $item) &&  array_key_exists('ext', $item) && array_key_exists('value', $item) && array_key_exists('sort', $item) ? true : false;
            }

            if (!$isFalse) {
                return self::ModelReturn(1, '自定义表单结构不正确');
            }
            $item['field_key'] = $item['type'] . '_';
            $allSort[] = $item['sort'];
        }

        $shouldSort = range(1, count($allSort));
        if (array_diff($shouldSort, $allSort)) {
            return self::ModelReturn(1, '自定义表单结构不正确,sort字段必须连续且不重复');
        }

        if (array_diff($allSort, $shouldSort)) {
            return self::ModelReturn(1, '自定义表单结构不正确,sort字段必须连续且不重复');
        }

        return self::ModelReturn(0, '', $formStruct);
    }

    /**
     * 创建自定义表单
     * @param $formName 自定义表单名称
     * @param $formStruct 自定义表单结构
     * @param int $objectId 对外功能需求的ID (扩展字段)
     * @param int $type 当前自定义表单类型 (扩展字段)
     * @param int $projectId 项目ID (扩展字段)
     * @return array
     */
    public static function createCustomerForm($formName, $formStruct, $objectId=0, $type=0, $projectId=0) {
        $formStructInfo = self::checkIsCustomerFormStruct($formStruct);
        if ($formStructInfo['code'] != 0) {
            return $formStructInfo;
        }
        $formStruct = $formStructInfo['data'];
        $createTime = time();
        $customerFormData = [
            'table_name'    =>  $formName ? : "form_" . time(),
            'status'        =>  self::$STATUS_OK,
            'create_time'   =>  $createTime,
            'update_time'   =>  $createTime,
            'project_id'    =>  $projectId,
            'type'          =>  $type,
            'object_id'     =>  $objectId
        ];

        try{
            Db::beginTransaction();
            $customerId = Db::table('sc_customer_form')->insertGetId($customerFormData);
            $customerFormKeyData = [];
            foreach ($formStruct as $struct) {
                $customerFormKeyData[] = [
                    'customer_form_id'  =>  $customerId,
                    'type'              =>  $struct['type'],
                    'label'             =>  $struct['label'],
                    'field_key'         =>  $struct['field_key'],
                    'ext'               =>  $struct['ext'],
                    'value'             =>  $struct['value'],
                    'sort'              =>  $struct['sort']
                ];
            }
            Db::table('sc_customer_form_key')->insert($customerFormKeyData);
            Db::table('sc_customer_form_key')->where('customer_form_id', $customerId)->update([
                'field_key' =>  Db::raw("concat(field_key,id)")
            ]);
            Db::commit();
            return self::ModelReturn(0, '创建成功', $customerId);
        } catch (\Exception $exception) {
            Db::rollback();
            return self::ModelReturn(1, $exception->getMessage());
        }
    }

    /**
     * 修改自定义表单
     * @param $customerId 自定义表单ID
     * @param $formName 自定义表单名称
     * @param $formStruct 自定义表达结构
     * @param int $projectId 项目ID (扩展字段)
     * @return array
     */
    public static function editCustomerForm($customerId, $formName, $formStruct, $projectId=0) {
        $customerFormObj = Db::table('sc_customer_form')->where(['id'=>$customerId, 'project_id'=>$projectId])->first();

        if (!$customerFormObj) {
            return self::ModelReturn(1, '表单不存在');
        }

        $formStructInfo = self::checkIsCustomerFormStruct($formStruct, true);
        if ($formStructInfo['code'] != 0) {
            return $formStructInfo;
        }
        $formStruct = $formStructInfo['data'];
        $createTime = time();
        $customerFormData = [
            'table_name'    =>  $formName,
            'update_time'   =>  $createTime
        ];

        try{
            Db::beginTransaction();
            Db::table('sc_customer_form')->where('id', $customerId)->update($customerFormData);

            $allNotNeedDeleteId = [];
            $customerFormKeyData = [];
            foreach ($formStruct as $struct) {
                if ($struct['id'] != 0) {
                    $tempUpdateData = [
                        'label'             =>  $struct['label'],
                        'ext'               =>  $struct['ext'],
                        'value'             =>  $struct['value'],
                        'sort'              =>  $struct['sort']
                    ];
                    Db::table('sc_customer_form_key')->where(['id'=>$struct['id'], 'customer_form_id'=>$customerId])->update($tempUpdateData);
                    $allNotNeedDeleteId[] = $struct['id'];
                    continue;
                }
                $customerFormKeyData[] = [
                    'customer_form_id'  =>  $customerId,
                    'type'              =>  $struct['type'],
                    'label'             =>  $struct['label'],
                    'field_key'         =>  $struct['field_key'],
                    'ext'               =>  $struct['ext'],
                    'value'             =>  $struct['value'],
                    'sort'              =>  $struct['sort']
                ];
            }

            if ($allNotNeedDeleteId) {
                Db::table('sc_customer_form_key')->whereNotIn('id', $allNotNeedDeleteId)->where('customer_form_id', $customerId)->delete();
            } else {
                Db::table('sc_customer_form_key')->where('customer_form_id', $customerId)->delete();
            }

            if ($customerFormKeyData) {
                Db::table('sc_customer_form_key')->insert($customerFormKeyData);
                Db::table('sc_customer_form_key')->whereNotIn('id', $allNotNeedDeleteId)->where('customer_form_id', $customerId)->update([
                    'field_key' =>  Db::raw("concat(field_key,id)")
                ]);
            }

            Db::commit();
            return self::ModelReturn(0, '编辑成功', $customerId);
        } catch (\Exception $exception) {
            Db::rollback();
            return self::ModelReturn(1, $exception->getMessage());
        }
    }

    /**
     * 更新自定义表单状态
     * @param $customerId 自定义表单ID
     * @param $status 状态
     * @param int $projectId 项目ID (扩展字段)
     * @return array
     */
    public static function changeCustomerFormStatus($customerId, $status, $projectId=0) {
        $customerFormObj = Db::table('sc_customer_form')->where(['id'=>$customerId, 'project_id'=>$projectId])->first();

        if (!$customerFormObj) {
            return self::ModelReturn(1, '表单不存在');
        }

        try {
            Db::table('sc_customer_form')->where(['id'=>$customerId, 'project_id'=>$projectId])->update([
                'status'    =>  $status,
                'update_time'   =>  time()
            ]);
            return self::ModelReturn(0, '更新成功');
        } catch (\Exception $exception) {
            return self::ModelReturn(2, $exception->getMessage());
        }
    }

    /**
     * 模型数据返回规范格式
     * @param int $code
     * @param string $msg
     * @param array $data
     * @return array
     */
    private static function ModelReturn($code = 0, $msg='', $data=[]) {
        return [
            'code'  =>  (int)$code,
            'msg'   =>  $msg,
            'data'  =>  $data
        ];
    }

    /**
     * 获取某个表单结构
     * @param $customerId 自定义表ID
     * @param int $projectId 项目ID (扩展字段)
     * @return array
     */
    public static function getCustomerForm($customerId, $projectId=0) {
        $customerFormObj = Db::table('sc_customer_form')->where(['id'=>$customerId, 'project_id'=>$projectId])->first();

        if (!$customerFormObj) {
            return self::ModelReturn(1, '自定义表单结构不存在');
        }
        $customerFormObj = DbObjectToArr($customerFormObj);
        $customerFormObj['createTimeStr'] = date("Y-m-d H:i:s", $customerFormObj['create_time']);
        $customerFormObj['updateTimeStr'] = date("Y-m-d H:i:s", $customerFormObj['update_time']);
        $allCustomerFormKeyData = Db::table('sc_customer_form_key')->where('customer_form_id', $customerId)->orderBy('sort')->get();
        $allCustomerFormKeyData = DbObjectToArr($allCustomerFormKeyData);
        return self::ModelReturn(0, '获取成功', [
            'customerForm'  =>  $customerFormObj,
            'customerFormKeyList'   =>  $allCustomerFormKeyData
        ]);
    }

    /**
     * 获取自定义表单数据
     * @param $customerFormListId 自定义表单实际数据表ID
     * @param int $projectId 项目ID (扩展字段)
     * @return array
     */
    public static function getCustomerFormListData($customerFormListId, $projectId=0) {
        $customerFormListData = Db::table('sc_customer_form_list')->where(['id'=>$customerFormListId, 'project_id'=>$projectId])->first();
        if (!$customerFormListData) {
            return self::ModelReturn(1, '自定义表单数据不存在');
        }
        $customerFormListData = DbObjectToArr($customerFormListData);
        $customerFormDataObj = self::getCustomerForm($customerFormListData['customer_form_id'], $projectId);
        if ($customerFormDataObj['code'] != 0) {
            return self::ModelReturn(2, $customerFormDataObj['msg']);
        }
        $customerFormData = $customerFormDataObj['data'];

        $customerFormListData['createTimeStr'] = date("Y-m-d H:i:s", $customerFormListData['create_time']);
        $customerFormListData['updateTimeStr'] = date("Y-m-d H:i:s", $customerFormListData['update_time']);
        $customerFormListValueData = Db::table('sc_customer_form_list_content')->where('customer_form_list_id', $customerFormListId)->get();
        $customerFormListValueData = DbObjectToArr($customerFormListValueData);
        $data = [
            'customerForm'          =>  $customerFormData,
            'customerFormListData'  =>  $customerFormListData,
            'customerFormListContentData'   =>  $customerFormListValueData
        ];

        return self::ModelReturn(0, '获取成功', $data);
    }

    /**
     * 检查自定义表单数据填写结构
     * @param $customerId 自定义表单ID
     * @param $formDataStruct 自定义表单结构
     * @return array
     */
    public static function checkIsCustomerFormListStruct($customerId, $formDataStruct) {
        if (is_string($formDataStruct)) {
            $formDataStruct = json_decode($formDataStruct, true);
        }

        if (!is_array($formDataStruct) || !$formDataStruct) {
            return self::ModelReturn(1, '表单数据结构不正确');
        }

        $allCustomerFormKeyIdList = [];
        foreach ($formDataStruct as &$item) {
            $isFalse = array_key_exists('customer_form_key_id', $item) && array_key_exists('field_value', $item) ? true : false;

            if (!$isFalse) {
                return self::ModelReturn(1, '表单数据结构不正确');
            }
            $allCustomerFormKeyIdList[] = $item['customer_form_key_id'];
        }

        $allCustomerFormKeyIdList = array_unique($allCustomerFormKeyIdList);
        if (count($allCustomerFormKeyIdList) != count($formDataStruct)) {
            return self::ModelReturn(2, '数据结构中customer_form_key_id不能重复');
        }

        if ($allCustomerFormKeyIdList) {
            $tempCustomerFormKey = Db::table('sc_customer_form_key')->where('customer_form_id', $customerId)->whereIn('id', $allCustomerFormKeyIdList)->pluck('id');
            $tempCustomerFormKey = DbObjectToArr($tempCustomerFormKey);
            if (array_diff($tempCustomerFormKey, $allCustomerFormKeyIdList)) {
                return self::ModelReturn(3, '数据结构中customer_form_key_id与表结构的字段列表不匹配');
            }

            if (array_diff($allCustomerFormKeyIdList, $tempCustomerFormKey)) {
                return self::ModelReturn(3, '数据结构中customer_form_key_id与表结构的字段列表不匹配');
            }
        }

        return self::ModelReturn(0, '验证通过');
    }

    /**
     * 添加自定义表单结构的数据
     * @param $customerFormId 自定义表单ID
     * @param $customerFormData 自定义表单数据
     * @param $userId 创建者ID
     * @param int $objectId 对外功能需求的ID (扩展字段)
     * @param int $type 当前自定义表单类型 (扩展字段)
     * @param int $projectId 项目ID (扩展字段)
     * @return array
     */
    public static function addCustomerFormListData($customerFormId, $customerFormData, $userId=0, $objectId=0, $type = 0, $projectId = 0) {
        $customerFormData = is_array($customerFormData) ? $customerFormData : json_decode($customerFormData, true);
        $customerObj = Db::table('sc_customer_form')->where(['id'=>$customerFormId, 'project_id'=>$projectId])->first();
        if (!$customerObj) {
            return self::ModelReturn(1, '自定义表结构不存在，提交失败');
        }
        $dataStructCheck = CustomerFormEngine::checkIsCustomerFormListStruct($customerFormId, $customerFormData);
        if ($dataStructCheck['code'] != 0) {
            return self::ModelReturn(2, $dataStructCheck['msg']);
        }

        $createTime = time();
        $customerFormListData = [
            'customer_form_id'  =>  $customerFormId,
            'create_user'       =>  $userId,
            'create_time'       =>  $createTime,
            'update_time'       =>  $createTime,
            'status'            =>  1,
            'project_id'        =>  $projectId,
            'type'              =>  $type,
            'object_id'         =>  $objectId
        ];

        $customerFormListContentData = [];
        try {
            Db::beginTransaction();
            $customerFormListId = Db::table('sc_customer_form_list')->insertGetId($customerFormListData);
            foreach ($customerFormData as $item) {
                $customerFormListContentData[] = [
                    'customer_form_list_id' =>  $customerFormListId,
                    'customer_form_key_id'  =>  $item['customer_form_key_id'],
                    'field_value'           =>  $item['field_value']
                ];
            }

            if ($customerFormListContentData) {
                Db::table('sc_customer_form_list_content')->insert($customerFormListContentData);
            }
            Db::commit();
            return self::ModelReturn(0, '提交自定义表单数据成功', $customerFormListId);
        } catch (\Exception $e) {
            Db::rollback();
            return self::ModelReturn(3, '提交自定义表单数据失败:' . $e->getMessage());
        }
    }
}
